﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Web_App___AWS_ELB_Monitor.Entities;
using Web_App___AWS_ELB_Monitor.Foundation;
using Web_App___AWS_ELB_Monitor.Models.AS;

namespace Web_App___AWS_ELB_Monitor.Controllers
{
    public class ASController : Controller
    {
        //
        // GET: /AS/
        public ASController()
        {

        }

        public ActionResult AutoScaleGroups()
        {
            var model = ASDataHelper.GetAllASGroups().Select(group => new AutoScaleGroupStatus
                                                                             {
                                                                                 Name = group.AutoScalingGroupName,
                                                                                 LoadBalancerName = group.LoadBalancerNames.FirstOrDefault(),
                                                                                 MinInstanceCount = group.MinSize,
                                                                                 MaxInstanceCount = group.MaxSize,
                                                                                 DesiredInstanceCount = group.DesiredCapacity
                                                                             }).ToList();

            return Json(new { AutoScaleGroups = model }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult AutoScaleGroup(string autoScaleGroupName)
        {
            var requestedASGroup = ASDataHelper.GetAS(autoScaleGroupName);

            // Get AS info:
            //  -  How many instances are currently provisioned (and min/max)
            int asMaxInstances = requestedASGroup.MaxSize;
            int asMinInstances = requestedASGroup.MinSize;
            int asDesiredCapacity = requestedASGroup.DesiredCapacity;


            // Get ELB associated with AS group:
            var loadBalancerName = requestedASGroup.LoadBalancerNames.FirstOrDefault();


            dynamic model = new ExpandoObject();
            model.AutoScaleGroupName = autoScaleGroupName;
            model.LoadBalancerName = loadBalancerName;
            model.CurrentMinInstances = asMinInstances;
            model.CurrentMaxInstances = asMaxInstances;
            model.CurrentDesiredCapacity = asDesiredCapacity;
            return View("ASDashboard", model);
        }

        public ActionResult DesiredCapacityHistory(string autoScaleGroupName)
        {
            //  -  24hr history of instance count
            var asInstanceCapacityToday = CloudWatchDataHelper.Get24HrPeriodDesiredCapacityCountForASG(autoScaleGroupName, onlyTime: true).ToList();
            var asInstanceCapacityYesterday = CloudWatchDataHelper.Get24HrPeriodDesiredCapacityCountForASG(autoScaleGroupName, DateTimeOffset.UtcNow.AddDays(-1), onlyTime: true).ToList();
            var asInstanceCapacityHistory = new[] { asInstanceCapacityToday, asInstanceCapacityYesterday }.ToDatePointGraph().OrderBy(data => data.TimeStamp).Select(graph =>
                                                                                                                                                                   new
                                                                                                                                                                       {
                                                                                                                                                                           Date = graph.TimeStamp.ToString("HH:mm"),
                                                                                                                                                                           Data = graph.Value
                                                                                                                                                                       });
            return Json(new { Data = asInstanceCapacityHistory }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult AllCpuHistory(string autoScaleGroupName)
        {
            var utcNow = DateTimeOffset.UtcNow;

            //  -  24hr history of CPU with instances in AS group

            var cpuUsageTodaySoFar = CloudWatchDataHelper.GetMetricsForEC2InstancesInASG(autoScaleGroupName, utcNow.TimeToZero(), utcNow, AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).ToList();
            var cpuUsageYesterday = CloudWatchDataHelper.GetMetricsForEC2InstancesInASG(autoScaleGroupName, utcNow.AddDays(-1).TimeToZero(), utcNow.TimeToZero(), AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).ToList();
            cpuUsageTodaySoFar.ForEach(point => point.TimeStamp = point.TimeStamp.TodaySameTime());
            cpuUsageYesterday.ForEach(point => point.TimeStamp = point.TimeStamp.TodaySameTime());
            var asCpuUsageHistory = new[] { cpuUsageTodaySoFar, cpuUsageYesterday }.ToDatePointGraph().OrderBy(data => data.TimeStamp).Select(graph =>
                                            new
                                            {
                                                Date = graph.TimeStamp.ToString("HH:mm"),
                                                Data = graph.Value
                                            }
                                            );

            // The AWS API sometimes returns no data for the last 60 seconds, so get the last 120 seconds, order by timestamp descending and get the first result
            var cpuNow = CloudWatchDataHelper.GetMetricsForEC2InstancesInASG(autoScaleGroupName, utcNow.AddSeconds(-120), utcNow, AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).OrderByDescending(x => x.TimeStamp).FirstOrDefault();

            return Json(new { Data = asCpuUsageHistory, CurrentValue = Math.Round(cpuNow.Value, 2) }, JsonRequestBehavior.AllowGet);
        }


        public ActionResult InstanceCpuHistory(List<string> instanceIds)
        {
            var instanceCpuHistory = new List<object>();

            var utcNow = DateTimeOffset.UtcNow;

            string[] badInstances;
            var instances = EC2DataHelper.GetInstances(instanceIds.ToArray()).InstanceDescriptions.ReadInstancesFromLoadBalancer().ToList();

            foreach (var instanceId in instanceIds)
            {
                var cpuUsageTodaySoFar = CloudWatchDataHelper.GetMetricsForEC2Instance(instanceId, utcNow.TimeToZero(), utcNow, AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).ToList().FillDataPoints(utcNow);
                var cpuUsageYesterday = CloudWatchDataHelper.GetMetricsForEC2Instance(instanceId, utcNow.AddDays(-1).TimeToZero(), utcNow.TimeToZero(), AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).ToList().FillDataPoints(utcNow);

                cpuUsageTodaySoFar.ForEach(point => point.TimeStamp = point.TimeStamp.TodaySameTime());
                cpuUsageYesterday.ForEach(point => point.TimeStamp = point.TimeStamp.TodaySameTime());

                var asCpuUsageHistory = new[] { cpuUsageTodaySoFar, cpuUsageYesterday }.ToDatePointGraph().OrderBy(data => data.TimeStamp).Select(graph =>
                                                new
                                                {
                                                    Date = graph.TimeStamp.ToString("HH:mm"),
                                                    Data = graph.Value
                                                }
                                                );

                // The AWS API sometimes returns no data for the last 60 seconds, so get the last 120 seconds, order by timestamp descending and get the first result
                var cpuNow = CloudWatchDataHelper.GetMetricsForEC2Instance(instanceId, utcNow.AddSeconds(-120), utcNow, AnalyticsValueType.Maximum, CloudWatchDefaultMetricEC2.CPUUtilization, "Percent", periodSeconds: 60).OrderByDescending(x => x.TimeStamp).FirstOrDefault();

                var instance = instances.FirstOrDefault(x => x.InstanceId == instanceId);
                var friendlyName = instance == null ? "" : EC2DataHelper.GetInstanceFriendlyName(instance);

                instanceCpuHistory.Add(new { Data = asCpuUsageHistory, CurrentValue = Math.Round(cpuNow.Value, 2), InstanceId = instanceId, FriendlyName = friendlyName });
            }

            return Json(instanceCpuHistory, JsonRequestBehavior.AllowGet);
        }
    }
}
